home *** CD-ROM | disk | FTP | other *** search
/ Super PC 31 / Super PC 31 (Shareware).iso / spc / inter / speakf / fuente / dialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-07  |  36.7 KB  |  1,198 lines

  1. /*
  2.  
  3.                 Dialogue procedures
  4.  
  5. */
  6.  
  7. #include "netfone.h"
  8.  
  9. typedef struct _NEW_HOST_PARAMS {
  10.     LPSTR pszHostName;
  11.     LPIN_ADDR paddr;
  12.     HANDLE hAsync;
  13.     ULONG laddr;
  14.     BYTE bBuffer[MAXGETHOSTSTRUCT];
  15. } NEW_HOST_PARAMS, FAR *LPNEW_HOST_PARAMS;
  16.  
  17. NEW_HOST_PARAMS NewHostParams;          // Parameters for NewHost dialog
  18.  
  19. //    SESSIONKEYGENERATE  --  Generate a random session key
  20.  
  21. void sessionKeyGenerate(LPSTR key, BOOL binary)
  22. {
  23.     int j, k;
  24.     char s[256];
  25.     struct MD5Context md5c;
  26.     char md5key[16], md5key1[16];
  27.     POINT p;
  28.     
  29.     /*    The following gets all kind of information likely
  30.         to vary from moment to moment and uses it as the initial
  31.         seed for the random number generator.  If any of these
  32.         causes porting problems in the future, just delete them.  */
  33.     
  34.     wsprintf(s, Format(28), GetTickCount());
  35.     wsprintf(s + strlen(s), Format(28), time(NULL));
  36.     gethostname(s + strlen(s), 256);
  37.     wsprintf(s + strlen(s), Format(29), GetActiveWindow());
  38.     wsprintf(s + strlen(s), Format(28), GetFreeSpace(0));
  39.     wsprintf(s + strlen(s), Format(29), GetFreeSystemResources(GFSR_SYSTEMRESOURCES)); 
  40.     wsprintf(s + strlen(s), Format(29), GetFreeSystemResources(GFSR_GDIRESOURCES)); 
  41.     wsprintf(s + strlen(s), Format(29), GetFreeSystemResources(GFSR_USERRESOURCES));
  42.     GetCursorPos(&p);
  43.     wsprintf(s + strlen(s), Format(30), p.x, p.y); 
  44.     MD5Init(&md5c);
  45.     MD5Update(&md5c, s, strlen(s));
  46.     MD5Final(md5key, &md5c);
  47.     wsprintf(s + strlen(s), Format(28), (time(NULL) + 65121) ^ 0x375F);
  48.     MD5Init(&md5c);
  49.     MD5Update(&md5c, s, strlen(s));
  50.     MD5Final(md5key1, &md5c);
  51.     init_idearand(md5key, md5key1, time(NULL));
  52.     for (j = k = 0; j < 16; j++) {
  53.         unsigned char rb = idearand();
  54.         
  55.         if (binary) {
  56.             key[j] = (char) rb;
  57.         } else {
  58. #define Rad16(x) ((x) + 'A')
  59.             key[k++] = Rad16((rb >> 4) & 0xF);
  60.             key[k++] = Rad16(rb & 0xF);
  61.             if (j & 1) {
  62.                 key[k++] = '-';
  63.             }
  64.         }
  65.     }
  66.     if (!binary) {
  67.         key[--k] = 0;
  68.     }
  69.     close_idearand();
  70. }
  71.  
  72. /*  MAKEINTERNALENCRYPTIONKEYS  --  Create actual encryption keys from user
  73.                                     specified keys.  */
  74.  
  75. int makeInternalEncryptionKeys(HWND hwnd, LPCLIENT_DATA d)
  76. {
  77.     if (IN_MULTICAST(d->inetSock.sin_addr.s_addr)) {
  78.     
  79.         /* Windows 95 WINSOCK bombs with an "out of range address"
  80.            when a char is passed as the multicast TTL optval, as
  81.            one does on Unix and which works fine with Trumpet
  82.            Winsock.  Work-around by allowing the user to send either
  83.            a char or an int.  Trumpet happens to work OK if you pass
  84.            an int, but there's probably some other WINSOCK that won't
  85.            accept a length of 2 for this argument. */
  86.     
  87.         if (waNetMultiTTLisChar) {
  88.             unsigned char scope = d->multicast_scope;
  89.         
  90.             if (setsockopt(d->sReply, IPPROTO_IP, IP_MULTICAST_TTL,
  91.                             (char *) &scope, sizeof scope) == -1) {
  92.                 int serr = WSAGetLastError();
  93.                 
  94.                 MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(38),
  95.                         d->szHost, serr, SockerrToString(serr));
  96.             }
  97.         } else {
  98.             int scope = d->multicast_scope;
  99.         
  100.             if (setsockopt(d->sReply, IPPROTO_IP, IP_MULTICAST_TTL,
  101.                             (char *) &scope, sizeof scope) == -1) {
  102.                 int serr = WSAGetLastError();
  103.                 
  104.                 MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(38),
  105.                         d->szHost, serr, SockerrToString(serr));
  106.             }
  107.         }
  108.     }
  109.  
  110.     if ((d->deskey[0] = (_fstrlen(d->desKeyString) > 0)) == TRUE) {
  111.         int j;
  112.         struct MD5Context md5c;
  113.         char md5key[16];
  114.                         
  115.         MD5Init(&md5c);
  116.         MD5Update(&md5c, d->desKeyString, _fstrlen(d->desKeyString));
  117.         MD5Final(md5key, &md5c);
  118.         for (j = 0; j < 8; j++) {
  119.             d->deskey[j + 1] = (char)
  120.                           ((md5key[j] ^ md5key[j + 8]) & 0x7F);
  121.         }
  122.     }
  123.     
  124.     if ((d->ideakey[0] = (_fstrlen(d->ideaKeyString) > 0)) == TRUE) {
  125.         struct MD5Context md5c;
  126.                         
  127.         MD5Init(&md5c);
  128.         MD5Update(&md5c, d->ideaKeyString, _fstrlen(d->ideaKeyString));
  129.         MD5Final(d->ideakey + 1, &md5c);
  130.     }
  131.     
  132.     if (d->opgpUserList[0]) {
  133.         char cmd[256];
  134.         HFILE kfile;
  135.         
  136.         sessionKeyGenerate(d->opgpkey + 1, TRUE);
  137.         d->opgpkey[0] = FALSE;
  138.         GetTempFileName(0, "PK", 0, d->opgpFileName);
  139.     
  140.         kfile = _lcreat(d->opgpFileName, 0);
  141.         if (kfile == NULL) {
  142.             MessageBox(hwnd, rstring(IDS_T_PGP_OPEN_SESSION_ERR),
  143.                 rstring(IDS_T_PGP_ENCODING_TITLE), MB_ICONEXCLAMATION | MB_OK);
  144.         } else {
  145.             UINT execStat = 0;
  146.         
  147.             _lwrite(kfile, "K", 1);
  148.             _lwrite(kfile, d->opgpkey + 1, 16);
  149.             _lclose(kfile);
  150.             
  151.             /*    First try to run PGP via the PIF in our own directory.  This
  152.                 guarantees it's run with the modes we've chosen, such as
  153.                 in a window rather than full-screen.  */
  154.             
  155.             if (GetModuleFileName(hInst, cmd, sizeof cmd) > 0) {
  156.                 char *cp = cmd + strlen(cmd);
  157.                 
  158.                 while (cp >= cmd && *cp != '\\' && *cp != ':') {
  159.                     cp--;
  160.                 }
  161.                 cp[1] = 0;
  162.                 wsprintf(cmd + strlen(cmd), Format(53),
  163.                          d->opgpFileName, d->opgpUserList + 1);
  164.                 execStat = WinExec(cmd, SW_SHOW); 
  165.             }
  166.  
  167.             /*    If that didn't work, attempt to run PGP by straight path
  168.                 search using the default modes.  */
  169.                 
  170.             if (execStat < 32) {                       
  171.                 wsprintf(cmd, Format(31), d->opgpFileName, d->opgpUserList + 1);
  172.                 execStat = WinExec(cmd, SW_SHOW);
  173.             }
  174.                 
  175.             //    Set timer to poll for completion of encoding
  176.                 
  177.             if (execStat >= 32) {
  178.                 d->opgpFileName[_fstrlen(d->opgpFileName) - 3] = 0;
  179.                 _fstrcat(d->opgpFileName, "PGP");
  180.                 SetTimer(hwnd, 4, 1000, NULL);
  181.             } else {
  182.                 wsprintf(cmd + strlen(cmd), Format(51), execStat);
  183.                 MessageBox(hwnd, cmd, rstring(IDS_T_CANT_INVOKE_PGP_ENCODE),
  184.                        MB_OK | MB_ICONEXCLAMATION);
  185.             }
  186.         }
  187.     }
  188.     
  189.     if (d->otpFileName[0]) {
  190.         HFILE fp = _lopen(d->otpFileName, READ);
  191.         if (fp == HFILE_ERROR) {
  192.             MessageBox(hwnd, rstring(IDS_T_PGP_KEY_OPEN_ERR),
  193.                 NULL, MB_ICONEXCLAMATION | MB_OK);
  194.             return FALSE;
  195.         } else {
  196.             UINT j, k, l = _lread(fp, d->otp, BUFL);
  197.             if (l == 0) {
  198.                 /* Idiot supplied void key file.  Give 'im
  199.                    what he asked for: no encryption. */
  200.                 d->otp[0] = 0;
  201.                 l = 1;
  202.             }
  203.             /* If the file is shorter than the maximum buffer
  204.                we may need to encrypt, replicate the key until
  205.                the buffer is filled. */
  206.             j = l;
  207.             k = 0;
  208.             while (j < BUFL) {
  209.                 d->otp[j++] = d->otp[k++];
  210.                 if (k >= l) {
  211.                     k = 0;
  212.                 }
  213.             }
  214.             _lclose(fp);
  215.         }
  216.     }
  217.     return TRUE; 
  218. }
  219.  
  220. //    CP_PROC  --  Connection properties dialogue procedure
  221.  
  222. static LPCLIENT_DATA clientData;
  223.  
  224. BOOL CALLBACK CP_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  225. {
  226.     LPCLIENT_DATA d = clientData;
  227.  
  228.     switch (message) {
  229.         case WM_INITDIALOG:
  230.             {
  231.                 char tbuf[132];
  232.                 
  233.                 //    Display host name in dialogue title
  234.                 
  235.                 if (d->inetSock.sin_addr.s_addr == 0) {
  236.                     strcpy(tbuf, rstring(IDS_T_MODEM_SP));
  237.                     GetWindowText(hDlg, tbuf + strlen(tbuf), (sizeof tbuf) - strlen(tbuf));
  238.                 } else {
  239.                     GetWindowText(hDlg, tbuf, sizeof tbuf);
  240.                     _fstrcat(tbuf, " - ");
  241.                     _fstrcat(tbuf, d->szHost);
  242.                 }
  243.                 SetWindowText(hDlg, tbuf);
  244.                 CheckDlgButton(hDlg, IDC_DEBUG, d->debugging);
  245.                 CheckDlgButton(hDlg, IDC_LOOPBACK, d->loopback);
  246.                 SetDlgItemText(hDlg, IDC_CP_DESKEY, d->desKeyString);
  247.                 SetDlgItemText(hDlg, IDC_CP_IDEAKEY, d->ideaKeyString);
  248.                 SetDlgItemText(hDlg, IDC_CP_OTPFILE, d->otpFileName);
  249.                 SetDlgItemText(hDlg, IDC_CP_PGPUSERS, d->opgpUserList);
  250.                 CheckDlgButton(hDlg, IDC_SAVE_KEYS, d->saveKeys);
  251.                 EnableWindow(GetDlgItem(hDlg, IDC_CP_MULTI_SCOPE),
  252.                     IN_MULTICAST(d->inetSock.sin_addr.s_addr));
  253.                 EnableWindow(GetDlgItem(hDlg, IDC_CP_MULTI_LABEL),
  254.                     IN_MULTICAST(d->inetSock.sin_addr.s_addr));
  255.                 if (IN_MULTICAST(d->inetSock.sin_addr.s_addr)) {
  256.                     SetDlgItemInt(hDlg, IDC_CP_MULTI_SCOPE, d->multicast_scope, FALSE);
  257.                 }
  258.             }
  259.             break;
  260.  
  261.         case WM_COMMAND:
  262.             switch ((int) wParam) {
  263.                 case IDOK:
  264.                     if (GetDlgItemInt(hDlg, IDC_CP_MULTI_SCOPE, NULL, FALSE) > 255) {
  265.                         MessageBox(hDlg, rstring(IDS_T_MULTICAST_SCOPE_ERR),
  266.                             NULL, MB_ICONEXCLAMATION | MB_OK);
  267.                         return TRUE;
  268.                     }
  269.                     d->debugging = IsDlgButtonChecked(hDlg, IDC_DEBUG);
  270.                     d->loopback = IsDlgButtonChecked(hDlg, IDC_LOOPBACK);
  271.                     GetDlgItemText(hDlg, IDC_CP_DESKEY, d->desKeyString, sizeof d->desKeyString);
  272.                     GetDlgItemText(hDlg, IDC_CP_IDEAKEY, d->ideaKeyString, sizeof d->ideaKeyString);
  273.                     GetDlgItemText(hDlg, IDC_CP_OTPFILE, d->otpFileName, sizeof d->otpFileName);
  274.                     GetDlgItemText(hDlg, IDC_CP_PGPUSERS, d->opgpUserList, sizeof d->opgpUserList);
  275.                     d->multicast_scope = GetDlgItemInt(hDlg, IDC_CP_MULTI_SCOPE, NULL, FALSE);
  276.                     d->saveKeys = IsDlgButtonChecked(hDlg, IDC_SAVE_KEYS);
  277.                     if (!makeInternalEncryptionKeys(GetParent(hDlg), d)) {
  278.                         break;
  279.                     }
  280.                     EndDialog(hDlg, TRUE);
  281.                     break;
  282.  
  283.                 case IDCANCEL:
  284.                     EndDialog(hDlg, FALSE);
  285.                     break;
  286.                     
  287.                 case IDC_OTP_BROWSE:
  288.                      {
  289.                          OPENFILENAME ofn;
  290.                          char szString[MAX_PATH];
  291.             
  292.                         memset(&ofn, 0, sizeof(ofn));
  293.                         ofn.lStructSize = sizeof(OPENFILENAME);
  294.                         ofn.hwndOwner = hDlg;
  295.                         ofn.lpstrFilter = rfilter(IDS_T_KEY_FILE_FILTER);
  296.                         ofn.lpstrCustomFilter = NULL;
  297.                         strcpy(szString, "");
  298.                         ofn.lpstrFile = (LPSTR) szString;
  299.                         ofn.nMaxFile = sizeof(szString);
  300.                         ofn.lpstrInitialDir = NULL;
  301.                         ofn.lpstrTitle = rstring(IDS_T_OPEN_KEY_FILE_TITLE);
  302.                         ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_SHOWHELP;
  303.                         fileHelpKey = rstring(IDS_HELP_KEY_FILE);
  304.                         if (GetOpenFileName((LPOPENFILENAME) &ofn)) {
  305.                             SetDlgItemText(hDlg, IDC_CP_OTPFILE, szString);
  306.                             _fstrcpy(d->otpFileName, szString);
  307.                         }
  308.                     }
  309.                     break;
  310.                     
  311.                 case ID_HELP:
  312.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  313.                                 ((DWORD) (Lrstring(IDS_HELP_CONNPROP))));
  314.                     holped = TRUE;
  315.                     break;
  316.  
  317.                 default:
  318.                     break;
  319.             }
  320.             break;
  321.             
  322.         default:
  323.             if (message == fileOpenHelpButton && fileHelpKey != NULL) {
  324.                 WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  325.                             ((DWORD) (LPSTR) fileHelpKey));
  326.                 holped = TRUE;
  327.             }
  328.             break;            
  329.     }
  330.     return FALSE;
  331. }
  332.  
  333. //    CONNECTIONPROPERTIES  --  Set properties for an open connection
  334.  
  335. VOID connectionProperties(HWND hwnd, LPCLIENT_DATA d)
  336. {
  337.     FARPROC pfnDlg;
  338.  
  339.     pfnDlg = MakeProcInstance((FARPROC) CP_proc, hInst);
  340.     clientData = d;
  341.     DialogBox(hInst, MAKEINTRESOURCE(IDD_CONNECTION_PROPERTIES), hwnd, (DLGPROC) pfnDlg);
  342.     FreeProcInstance(pfnDlg);
  343.     return;
  344. }
  345.  
  346. //    GENKEYDLGPROC  --  Session key generator dialogue procedure
  347.  
  348. BOOL CALLBACK genKeyDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  349. {
  350.     switch (nMessage) {
  351.         case WM_INITDIALOG:
  352.             {
  353.                 char key[256];
  354.                 
  355.                 sessionKeyGenerate(key, FALSE);
  356.                 SetDlgItemText(hwnd, IDE_KEY, key);
  357.             }
  358.             break;
  359.                 
  360.         case WM_COMMAND:
  361.             switch ((int) wParam) {
  362.             
  363.                 case IDOK:
  364.                 EndDialog(hwnd, TRUE);
  365.                 break;
  366.                 
  367.                 case IDC_NEW_KEY:
  368.                     {
  369.                         char key[256];
  370.                         
  371.                         sessionKeyGenerate(key, FALSE);
  372.                         SetDlgItemText(hwnd, IDE_KEY, key);
  373.                         SendMessage(GetDlgItem(hwnd, IDE_KEY), EM_SETSEL, 0,
  374.                             MAKELONG(0, _fstrlen(key) + 1));
  375.                         SetFocus(GetDlgItem(hwnd, IDE_KEY));
  376.                     }
  377.                     break;
  378.                     
  379.                 case ID_HELP:
  380.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  381.                                 ((DWORD) (Lrstring(IDS_HELP_KEYGEN))));
  382.                     holped = TRUE;
  383.                     break;
  384.             }
  385.     }
  386.     return FALSE;
  387. }
  388.  
  389. //    GENKEYDIALOGUE  --  Generate session key dialogue
  390.  
  391. VOID genKeyDialogue(HWND hwnd)
  392. {
  393.     FARPROC pfn;
  394.  
  395.     pfn = MakeProcInstance((FARPROC) genKeyDlgProc, hInst);
  396.  
  397.     DialogBox(hInst, MAKEINTRESOURCE(IDD_GEN_KEY), hwnd, (DLGPROC) pfn);
  398.  
  399.     FreeProcInstance(pfn);
  400. }
  401.  
  402. //    RANT1_DLGPROC  --  First serial I/O rant dialogue procedure
  403.  
  404. BOOL CALLBACK rant1_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  405. {
  406.     switch (nMessage) {
  407.         case WM_COMMAND:
  408.             if (wParam == IDOK) {
  409.                 EndDialog(hwnd, TRUE);
  410.             } else if (wParam == IDCANCEL) {
  411.                 EndDialog(hwnd, FALSE);
  412.             }
  413.             break;
  414.     }
  415.     return FALSE;
  416. }
  417.  
  418. //    RANT1DIALOGUE  --  First serial I/O rant dialogue
  419.  
  420. int rant1Dialogue(HWND hwndParent)
  421. {
  422.     FARPROC pfn;
  423.     int result;
  424.  
  425.     pfn = MakeProcInstance((FARPROC) rant1_DlgProc, hInst);
  426.  
  427.     result = DialogBox(hInst, MAKEINTRESOURCE(IDD_MODEM_RANT), hwndParent, (DLGPROC) pfn);
  428.  
  429.     FreeProcInstance(pfn);
  430.     return result;
  431. }
  432.  
  433. //    RANT2_DLGPROC  --  Second serial I/O rant dialogue procedure
  434.  
  435. BOOL CALLBACK rant2_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  436. {
  437.     switch (nMessage) {
  438.         case WM_INITDIALOG:
  439.             CheckDlgButton(hwnd, IDC_RANT, modemShowRant);
  440.             break;
  441.         
  442.         case WM_COMMAND:
  443.             if (wParam == IDOK) {
  444.                 modemShowRant = IsDlgButtonChecked(hwnd, IDC_RANT);
  445.                 EndDialog(hwnd, TRUE);
  446.             } else if (wParam == IDCANCEL) {
  447.                 EndDialog(hwnd, FALSE);
  448.             }
  449.             break;
  450.     }
  451.     return FALSE;
  452. }
  453.  
  454. //    RANT2DIALOGUE  --  Second serial I/O rant dialogue
  455.  
  456. int rant2Dialogue(HWND hwndParent)
  457. {
  458.     FARPROC pfn;
  459.     int result;
  460.  
  461.     pfn = MakeProcInstance((FARPROC) rant2_DlgProc, hInst);
  462.     result = DialogBox(hInst, MAKEINTRESOURCE(IDD_MODEM_RANT_2), hwndParent, (DLGPROC) pfn);
  463.     FreeProcInstance(pfn);
  464.     return result;
  465. }
  466.  
  467. //    MODEMDLGPROC  --  Modem setup dialogue procedure
  468.  
  469. BOOL CALLBACK modemDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  470. {
  471. #ifndef CBR_28800
  472. #define CBR_28800    0xFF1A             // Missing in 3.1 windows.h
  473. #endif
  474.     static WORD baudRates[] = { CBR_9600, CBR_14400, CBR_19200, CBR_28800,
  475.                                 CBR_38400, CBR_56000, CBR_128000,
  476.                                  CBR_256000 };
  477.      static char *baudNames[] = { "9600", "14400", "19200", "28800", "38400",
  478.                                   "56000", "128000", "256000", NULL };
  479.     switch (nMessage) {
  480.         case WM_INITDIALOG:
  481.             {
  482.                 WORD i, n;
  483.                 HWND ctl = GetDlgItem(hwnd, IDD_MODEM_BAUD_RATE);
  484.                 WORD ncom = LOWORD(EscapeCommFunction(NULL, GETMAXCOM)) + 1;
  485.                 
  486.                 CheckDlgButton(hwnd, IDC_MODEM_ENABLE, modemEnable);
  487.                 SetDlgItemText(hwnd, IDC_MODEM_INIT_STRING, modemInitString);
  488.  
  489.                 for (i = 0; baudNames[i] != NULL; i++) {
  490.                     n = LOWORD(SendMessage(ctl, CB_ADDSTRING, NULL,
  491.                                            (LPARAM) (LPSTR) baudNames[i]));
  492.                     SendMessage(ctl, CB_SETITEMDATA, (WPARAM) n,
  493.                                     (LPARAM) (LONG) baudRates[i]);
  494.                                 
  495.                     if (strcmp(baudNames[i], baudrate) == 0) {
  496.                         SendMessage(ctl, CB_SETCURSEL, (WPARAM) n, NULL);
  497.                     }
  498.                 }
  499.                 
  500.                 ctl = GetDlgItem(hwnd, IDD_MODEM_PORT);
  501.                 for (i = 0; i < ncom; i++) {
  502.                     char comn[12];
  503.                     
  504.                     wsprintf(comn, Format(32), i + 1);
  505.                     n = LOWORD(SendMessage(ctl, CB_ADDSTRING, NULL,
  506.                                                    (LPARAM) (LPSTR) comn));
  507.                     SendMessage(ctl, CB_SETITEMDATA, (WPARAM) n,
  508.                                (LPARAM) (LONG) i + 1);
  509.                                 
  510.                     if (_fstrcmp(comn, commport) == 0) {
  511.                         SendMessage(ctl, CB_SETCURSEL, (WPARAM) n, NULL);
  512.                     }
  513.                 }
  514.             }
  515.             break;
  516.                 
  517.         case WM_COMMAND:
  518.             switch ((int) wParam) {
  519.                 case IDOK:
  520.                     {
  521.                         DWORD i;
  522.                         
  523.                         closeModem(hwnd);
  524.                         modemEnable = IsDlgButtonChecked(hwnd, IDC_MODEM_ENABLE);
  525.                         GetDlgItemText(hwnd, IDC_MODEM_INIT_STRING,
  526.                                         modemInitString, sizeof modemInitString);
  527.                                         
  528.                         i = SendDlgItemMessage(hwnd, IDD_MODEM_BAUD_RATE,
  529.                                 CB_GETCURSEL, 0, 0);
  530.                         if (i != CB_ERR) {
  531.                             SendDlgItemMessage(hwnd, IDD_MODEM_BAUD_RATE, CB_GETLBTEXT,
  532.                                 (WPARAM) i, (LPARAM) (LPCSTR) baudrate);    
  533.                         }
  534.                          
  535.                         i = SendDlgItemMessage(hwnd, IDD_MODEM_PORT,
  536.                                 CB_GETCURSEL, 0, 0);
  537.                         if (i != CB_ERR) {
  538.                             SendDlgItemMessage(hwnd, IDD_MODEM_PORT, CB_GETLBTEXT,
  539.                                 (WPARAM) i, (LPARAM) (LPCSTR) commport);    
  540.                         }
  541.                         if (modemEnable) {
  542.                             if (!openModem(hwnd)) {
  543.                                 modemEnable = FALSE;
  544.                             }
  545.                         } 
  546.                         EndDialog(hwnd, TRUE);
  547.                     }
  548.                     break;
  549.                     
  550.                 case IDCANCEL:
  551.                     EndDialog(hwnd, FALSE);
  552.                     break;
  553.                 
  554.                 case IDC_MODEM_ENABLE:
  555.                     if (modemShowRant && ((WORD)
  556.                             SendMessage(GetDlgItem(hwnd, IDC_MODEM_ENABLE),
  557.                                 BM_GETCHECK, 0, 0L))) {
  558.                         if (rant1Dialogue(hwnd)) {
  559.                             if (rant2Dialogue(hwnd)) {
  560.                                 break;
  561.                             } else {
  562.                                 CheckDlgButton(hwnd, IDC_MODEM_ENABLE, FALSE);
  563.                             }
  564.                         } else {
  565.                             CheckDlgButton(hwnd, IDC_MODEM_ENABLE, FALSE);
  566.                         }
  567.                     }
  568.                     break;
  569.                         
  570.                 case ID_HELP:
  571.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  572.                                 ((DWORD) (Lrstring(IDS_HELP_MODEM_CONFIG))));
  573.                     holped = TRUE;
  574.                     break;
  575.             }
  576.     }
  577.     return FALSE;
  578. }
  579.  
  580. //    MODEMRANT  --  Display rant about lousy serial I/O support on Windows
  581.  
  582. void modemRant(HWND hwnd)
  583. {
  584.     if (rant1Dialogue(hwnd)) {
  585.         rant2Dialogue(hwnd);
  586.     }
  587. }
  588.  
  589. //    MODEMSETUPDIALOGUE  --  Modem setup dialogue
  590.  
  591. VOID modemSetupDialogue(HWND hwnd)
  592. {
  593.     FARPROC pfn;
  594.      
  595.     pfn = MakeProcInstance((FARPROC) modemDlgProc, hInst);
  596.  
  597.     DialogBox(hInst, MAKEINTRESOURCE(IDD_MODEM_SETTINGS), hwnd, (DLGPROC) pfn);
  598.  
  599.     FreeProcInstance(pfn);
  600. }
  601.  
  602. //    MULTICASTDLGPROC  --  Multicast group membership dialogue procedure
  603.  
  604. BOOL CALLBACK multicastDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  605. {
  606.     switch (nMessage) {
  607.         case WM_INITDIALOG:
  608.             {
  609.                 int i;
  610.                 HWND ctl = GetDlgItem(hwnd, IDC_MC_GROUPS);
  611.             
  612.                 for (i = 0; i < multiMemberships; i++) {
  613.                     char mcline[MAX_HOST + 24];
  614.                     
  615.                     if (multiName[i] == NULL) {
  616.                         _fstrcpy(mcline, inet_ntoa(multiAddr[i])); 
  617.                     } else {
  618.                         wsprintf(mcline, Format(33), multiName[i],
  619.                             (LPSTR) inet_ntoa(multiAddr[i]));
  620.                     }
  621.                     SendMessage(ctl, LB_ADDSTRING, NULL,
  622.                         (LPARAM) (LPSTR) mcline);
  623.                 }
  624.                 SendMessage(ctl, LB_SETCURSEL, multiMemberships > 0 ? 0 : -1, 0L);
  625.                 CheckDlgButton(hwnd, IDC_MC_LOOP, multiLoop);
  626.                 EnableWindow(GetDlgItem(hwnd, IDC_MC_LOOP), !multiBrainDead);
  627.                 EnableWindow(GetDlgItem(hwnd, IDC_MC_LEAVE), multiMemberships > 0);
  628.                 EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN), FALSE);
  629.             }
  630.             break;
  631.                 
  632.         case WM_COMMAND:
  633.             switch ((int) wParam) {
  634.                 case IDOK:
  635.                     {
  636.                         int i, n;
  637.                         
  638.                         multicastJoin(hwnd, FALSE);    // Drop current groups
  639.                         multiLoop = IsDlgButtonChecked(hwnd, IDC_MC_LOOP);
  640.                         n = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETCOUNT, 0, 0L);
  641.                         for (i = 0; i < n; i++) {
  642.                             char s[MAX_HOST + 24];
  643.                             char *cp;
  644.                             
  645.                             SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETTEXT, i,
  646.                                 (LPARAM) (LPCSTR) s);
  647.                             if ((cp = strchr(s, '(')) != NULL) {
  648.                                 char *cp1;
  649.                                 
  650.                                 cp++;
  651.                                 cp1 = strchr(cp, ')');
  652.                                 if (cp1 != NULL) {
  653.                                     *cp1 = 0;
  654.                                 }
  655.                             } else {
  656.                                 cp = s;
  657.                             }
  658.                             multiAddr[i].s_addr = inet_addr(cp);
  659.                             multiName[i] = NULL;
  660.                             if (cp > s) {
  661.                                 LPSTR np;
  662.                                 
  663.                                 cp[-2] = 0;
  664.                                 np = GlobalAllocPtr(GPTR, strlen(s) + 1);
  665.                                 if (np != NULL) {
  666.                                     _fstrcpy(np, s);
  667.                                     multiName[i] = np;
  668.                                 }
  669.                             }
  670.                         }
  671.                         multiMemberships = n;
  672.                         multicastJoin(hwnd, TRUE);        // Join newly chosen groups
  673.                     }
  674.                     EndDialog(hwnd, TRUE);
  675.                     break;
  676.                     
  677.                 case IDCANCEL:
  678.                     EndDialog(hwnd, FALSE);
  679.                     break;
  680.                     
  681.                 case IDC_MC_NEW_GROUP:
  682.                     if (HIWORD(lParam) == EN_CHANGE) {
  683.                         EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN),
  684.                             (multiMemberships < IP_MAX_MEMBERSHIPS) &&
  685.                             (SendDlgItemMessage(hwnd, IDC_MC_NEW_GROUP, EM_LINELENGTH, 0, 0L) > 0));
  686.                     }
  687.                     break;
  688.                     
  689.                 case IDC_MC_JOIN:
  690.                     {
  691.                         char group[MAX_HOST];
  692.                         int l;
  693.                         struct in_addr newaddr;
  694.                         
  695.                         *((WORD *) group) = sizeof group;
  696.                         l = (int) SendDlgItemMessage(hwnd, IDC_MC_NEW_GROUP, EM_GETLINE,
  697.                             0, (LPARAM) (LPSTR) group);
  698.                         group[l] = 0;
  699.                         newaddr.s_addr = inet_addr(group);
  700.                         if (newaddr.s_addr == INADDR_NONE) {
  701.                             LPHOSTENT h = gethostbyname(group);
  702.                             
  703.                             if (h == NULL) {
  704.                                 int serr = WSAGetLastError();
  705.                                     
  706.                                 MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(39),
  707.                                         (LPSTR) group,
  708.                                         serr, SockerrToString(serr));
  709.                                 group[0] = 0;
  710.                             } else {
  711.                                 newaddr = *((LPIN_ADDR) h->h_addr); 
  712.                                 wsprintf(group + strlen(group), Format(34),
  713.                                     (LPSTR) inet_ntoa(newaddr));
  714.                             }
  715.                         }
  716.                         if (group[0] != 0 && !IN_MULTICAST(newaddr.s_addr)) {
  717.                             MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(35),
  718.                                     ((LPSTR) inet_ntoa(newaddr)));
  719.                             group[0] = 0;
  720.                         }
  721.                         if (group[0] != 0) {
  722.                             int nitem, ic;
  723.                                 
  724.                             //    Clear input field
  725.                             SetDlgItemText(hwnd, IDC_MC_NEW_GROUP, ""); 
  726.                             
  727.                             //    Make sure it's not already in the box
  728.                             nitem = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_FINDSTRINGEXACT,
  729.                                     (WPARAM) -1, (LPARAM) (LPCSTR) group); 
  730.                             if (nitem == LB_ERR) {
  731.                                 nitem = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_ADDSTRING, 0,
  732.                                     (LPARAM) (LPCSTR) group);
  733.                                 ic = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETCOUNT, 0, 0L);
  734.                                 EnableWindow(GetDlgItem(hwnd, IDC_MC_LEAVE), ic > 0);
  735.                                 EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN), FALSE);
  736.                             }
  737.                             if (nitem != LB_ERR) {
  738.                                 SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_SETCURSEL, nitem, 0L);
  739.                             }
  740.                         }
  741.                         //    Set focus back to the edit field
  742.                         SetFocus(GetDlgItem(hwnd, IDC_MC_NEW_GROUP));
  743.                     }
  744.                     break;
  745.                     
  746.                 case IDC_MC_LEAVE:
  747.                     {
  748.                         int item = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS,
  749.                                             LB_GETCURSEL, 0, 0L);
  750.                         if (item != LB_ERR) {
  751.                             int itemc;
  752.                             
  753.                             SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_DELETESTRING, item, 0L);
  754.                             itemc = (int) SendDlgItemMessage(hwnd, IDC_MC_GROUPS, LB_GETCOUNT, 0, 0L);
  755.                             EnableWindow(GetDlgItem(hwnd, IDC_MC_LEAVE), itemc > 0);
  756.                             EnableWindow(GetDlgItem(hwnd, IDC_MC_JOIN),
  757.                                 (itemc < IP_MAX_MEMBERSHIPS) &&
  758.                                 (SendDlgItemMessage(hwnd, IDC_MC_NEW_GROUP, EM_LINELENGTH, 0, 0L) > 0));
  759.                             SendDlgItemMessage(hwnd, IDC_MC_GROUPS,
  760.                                 LB_SETCURSEL, item >= itemc ? itemc - 1 : item, 0L);
  761.                         } 
  762.                     }
  763.                     break;
  764.                     
  765.                 case ID_HELP:
  766.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  767.                                 ((DWORD) (Lrstring(IDS_HELP_MULTICAST))));
  768.                     holped = TRUE;
  769.                     break;
  770.             }
  771.     }
  772.     return FALSE;
  773. }
  774.  
  775. //    MULTICASTGROUPSDIALOGUE  --  Multicast group membership dialogue
  776.  
  777. VOID multicastGroupsDialogue(HWND hwnd)
  778. {
  779.     FARPROC pfn;
  780.      
  781.     pfn = MakeProcInstance((FARPROC) multicastDlgProc, hInst);
  782.  
  783.     DialogBox(hInst, MAKEINTRESOURCE(IDD_MULTICAST), hwnd, (DLGPROC) pfn);
  784.  
  785.     FreeProcInstance(pfn);
  786. }
  787.  
  788.  
  789. //    ABOUT_DLGPROC  --  About dialogue procedure
  790.  
  791. BOOL CALLBACK About_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  792. {
  793.     switch (nMessage) {
  794.         case WM_INITDIALOG:
  795.         {
  796.             char s[80];
  797.             
  798.             if (aboutInSamples != 0) {
  799.                 _fstrcpy(s, inputActive ? rstring(IDS_T_ACTIVE) : rstring(IDS_T_IDLE));
  800.                 wsprintf(s + strlen(s), Format(50),
  801.                     aboutInSamples, aboutInBits);
  802.                 SetDlgItemText(hwnd, IDC_ABOUT_INPUT, s); 
  803.             } else {
  804.                 SetDlgItemText(hwnd, IDC_ABOUT_INPUT, rstring(IDS_T_NEVER_USED));
  805.             }
  806.  
  807.             if (aboutOutSamples != 0) {
  808.                 _fstrcpy(s, outputActive ? rstring(IDS_T_ACTIVE) : rstring(IDS_T_IDLE));
  809.                 wsprintf(s + strlen(s), Format(50),
  810.                     aboutOutSamples, aboutOutBits);
  811.                 SetDlgItemText(hwnd, IDC_ABOUT_OUTPUT, s); 
  812.             } else {
  813.                 SetDlgItemText(hwnd, IDC_ABOUT_OUTPUT, rstring(IDS_T_NEVER_USED));
  814.             }
  815.             
  816.             ShowWindow(GetDlgItem(hwnd, IDC_ABOUT_DUPLEX),
  817.                 halfDuplex ? SW_SHOW : SW_HIDE);
  818.         }
  819.         break;
  820.  
  821.     
  822.         case WM_COMMAND:
  823.             switch ((int) wParam) {
  824.             
  825.                 case IDOK:
  826.                     EndDialog(hwnd, TRUE);
  827.                     break;
  828.                     
  829.                 case ID_HELP:
  830.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  831.                                 ((DWORD) (Lrstring(IDS_HELP_ABOUT))));
  832.                     holped = TRUE;
  833.                     break;                    
  834.             }
  835.             break;
  836.     }
  837.     return FALSE;
  838. }
  839.  
  840. //    ABOUTDIALOGUE  --  About dialogue
  841.  
  842. VOID aboutDialogue(HWND hwndParent)
  843. {
  844.     FARPROC pfnAbout;
  845.  
  846.     pfnAbout = MakeProcInstance((FARPROC) About_DlgProc, hInst);
  847.  
  848.     DialogBox(hInst, IDD_ABOUT, hwndParent, (DLGPROC) pfnAbout);
  849.  
  850.     FreeProcInstance(pfnAbout);
  851. }
  852.  
  853. /*    PROPUPDATEAUDIO  --  Update audio configuration information in the
  854.                          propeller head panel.  */
  855.                          
  856. void propUpdateAudio(void)
  857. {
  858.     if (hDlgPropeller != NULL) {
  859.         char s[80];
  860.         
  861.         if (aboutInSamples != 0) {
  862.             _fstrcpy(s, inputActive ? rstring(IDS_T_ACTIVE_COMMA) : rstring(IDS_T_IDLE_COMMA));
  863.             wsprintf(s + strlen(s), Format(36),
  864.                 aboutInBits, aboutInSamples);
  865.             SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_IN, s); 
  866.         } else {
  867.             SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_IN, rstring(IDS_T_NONE));
  868.         }
  869.         
  870.         if (aboutOutSamples != 0) {
  871.             _fstrcpy(s, outputInShutdown ? rstring(IDS_T_TERMINATING_COMMA) :
  872.                 (halfDuplexTransition ? rstring(IDS_T_TRANSITION_COMMA) : 
  873.                 (outputActive ? rstring(IDS_T_ACTIVE_COMMA) : rstring(IDS_T_IDLE_COMMA))));
  874.             wsprintf(s + strlen(s), Format(36),
  875.                 aboutOutBits, aboutOutSamples);
  876.             SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT, s); 
  877.             wsprintf(s, outputPending == 0 ? Format(6) : Format(7),
  878.                         outputPending);
  879.             SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT_QUEUE, s);
  880.         } else {
  881.             SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT, rstring(IDS_T_NONE));
  882.         }
  883.         
  884.         SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_DUPLEX,
  885.             halfDuplex ? rstring(IDS_T_HALF_DUPLEX) : rstring(IDS_T_FULL_DUPLEX));
  886.             
  887.         SetDlgItemInt(hDlgPropeller, IDC_PH_CONNECTIONS, openConnections, FALSE);
  888.         SetDlgItemInt(hDlgPropeller, IDC_PH_PACKET_SENDSIZE, inputSampleCount(), FALSE);
  889.  
  890.         SetDlgItemText(hDlgPropeller, IDC_PH_COMPRESSION,
  891.                             rstring(IDS_COMPRESSION_TYPES + ((compression ? 1 : 0) |
  892.                                          (gsmcompress ? 2 : 0) |
  893.                                          (adpcmcompress ? 4 : 0) |
  894.                                          (lpccompress ? 8 : 0))));
  895.     }
  896. }                         
  897.  
  898. //    PROPELLERHEADDLGPROC  --  Propeller head dialogue procedure
  899.  
  900. BOOL CALLBACK propellerHeadDlgProc(HWND hwnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  901. {
  902.     switch (nMessage) {
  903.         case WM_INITDIALOG:
  904.             {
  905.                 char s[80];
  906.                 
  907.                 if (aboutUDPmax != 0) {
  908.                     wsprintf(s, Format(37), aboutUDPmax);
  909.                     SetDlgItemText(hwnd, IDC_PH_PACKET_SIZE, s); 
  910.                 }
  911. #define Prop(item, value) wsprintf(s, Format(0), value); SetDlgItemText(hwnd, item, s)                 
  912.                 Prop(IDC_PH_PACKETS_RECEIVED, packetsReceived);
  913.                 Prop(IDC_PH_PACKETS_SENT, packetsSent);
  914.                 Prop(IDC_PH_INPUT_LOST, inputPacketsLost);
  915.                 Prop(IDC_PH_OUTPUT_LOST, outputPacketsLost);
  916.                 Prop(IDC_PH_MESSAGE_QUEUE, (long) messageQueueSize);
  917.                 SetDlgItemText(hwnd, IDC_PH_SENDTO,
  918.                         useSendNotSendto ? rstring(IDS_T_SEND) : rstring(IDS_T_SENDTO));
  919. #undef Prop
  920.                 hDlgPropeller = hwnd;
  921.                 propUpdateAudio();                
  922.             }
  923.             return TRUE;
  924.             
  925.         case WM_CLOSE:
  926.             DestroyWindow(hwnd);
  927.             return TRUE;
  928.  
  929.         case WM_COMMAND:
  930.             switch ((int) wParam) {
  931.                 case IDOK:
  932.                     PostMessage(hwnd, WM_CLOSE, 0, 0L);
  933.                     break;
  934.                     
  935.                 case ID_HELP:
  936.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  937.                                 ((DWORD) (Lrstring(IDS_HELP_PROPELLER))));
  938.                     holped = TRUE;
  939.                     break;
  940.             }
  941.             return TRUE;
  942.             
  943.         case WM_DESTROY:
  944.             hDlgPropeller = NULL;
  945.             return 0;
  946.     }
  947.     return FALSE;
  948. }
  949.  
  950. //    PROPELLERHEADDIALOGUE  --  Expert status dialogue
  951.  
  952. VOID propellerHeadDialogue(HWND hwndParent)
  953. {
  954.     hDlgPropeller = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROPELLER_HEAD),
  955.                     hwndParent, (DLGPROC) pfnPropeller);
  956. }
  957.  
  958. /*  NEWHOST_ENABLECONTROLS  --  Enable/disable controls (other
  959.                                 than the Cancel button) in the New
  960.                                 Host dialogue.  */
  961.  
  962. static VOID NewHost_EnableControls(HWND hwnd, BOOL fEnable)
  963. {
  964.     EnableWindow(GetDlgItem(hwnd, IDD_NEW_HOST), fEnable);
  965.     EnableWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), fEnable);
  966.     EnableWindow(GetDlgItem(hwnd, IDOK), fEnable);
  967.  
  968.     /*  If we enabling the dialog controls, it is due to a
  969.         failure to retrieve the host data, so set the focus
  970.         to the host edit field.  If we're disabling the controls,
  971.         set the focus to the cancel button since that's the only
  972.         thing we haven't disabled. */
  973.  
  974.     SetFocus(GetDlgItem(hwnd, fEnable ? IDD_NEW_HOST : IDCANCEL));
  975. }
  976.  
  977. /*  NEWHOST_ONCOMMAND  --  Handle child control messages in the new
  978.                            host dialogue.  */
  979.  
  980. static VOID NewHost_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  981. {
  982.     HANDLE  hAsyncTask;
  983.     SOCKERR serr;
  984.  
  985.     //  Interpret the command
  986.  
  987.     switch (id) {
  988.     
  989.         case IDOK:
  990.             // handled below
  991.             break;
  992.     
  993.         case IDCANCEL:
  994.         
  995.             //  Cancel any pending async operation started by this dialog
  996.     
  997.             if (NewHostParams.hAsync != NULL) {
  998.                 WSACancelAsyncRequest(NewHostParams.hAsync);
  999.                 NewHostParams.hAsync = NULL;
  1000.             }
  1001.             EndDialog(hwnd, FALSE);
  1002.             return;
  1003.             
  1004.         case IDC_NEW_MODEM:
  1005.             {
  1006.                 if ((WORD) SendMessage(GetDlgItem(hwnd, IDC_NEW_MODEM),
  1007.                         BM_GETCHECK, 0, 0L)) {
  1008.                     ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), SW_HIDE);
  1009.                     ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_DIAL_STRING), SW_SHOW);
  1010.                 } else {
  1011.                     ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), SW_SHOW);
  1012.                     ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_DIAL_STRING), SW_HIDE);
  1013.                 }
  1014.             }
  1015.             return;
  1016.             
  1017.         case ID_HELP:
  1018.             WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  1019.                         ((DWORD) (Lrstring(IDS_HELP_NEWCONN))));
  1020.             holped = TRUE;
  1021.             return;
  1022.     
  1023.         default:
  1024.             return;
  1025.     }
  1026.  
  1027.     /*  We only make it to this point if the command was OK.
  1028.         Get the host name/address from the edit field. */
  1029.  
  1030.     Edit_GetText(GetDlgItem(hwnd, IDD_NEW_HOST), NewHostParams.pszHostName,
  1031.                   MAX_HOST);
  1032.  
  1033.     if (IsDlgButtonChecked(hwnd, IDC_NEW_MODEM)) {
  1034.         COMSTAT cs;
  1035.         
  1036.         if (modemSessions != 0) {
  1037.             MessageBox(hwnd, rstring(IDS_T_MODEM_BUSY), NULL, MB_ICONEXCLAMATION | MB_OK);
  1038.             return;
  1039.         }
  1040.         
  1041.         //    Send the modem dialing command
  1042.         
  1043.         V GetCommError(modemHandle, &cs);
  1044.         WriteComm(modemHandle, NewHostParams.pszHostName,
  1045.                     _fstrlen(NewHostParams.pszHostName));
  1046.         V GetCommError(modemHandle, &cs);
  1047.         WriteComm(modemHandle, "\r", 1);
  1048.         V GetCommError(modemHandle, &cs);
  1049.                      
  1050.         //    Zero Internet address indicates modem connection
  1051.         
  1052.         _fmemset(NewHostParams.paddr, 0, sizeof(IN_ADDR));
  1053.         
  1054.         EndDialog(hwnd, TRUE);
  1055.     } else {
  1056.         if (NewHostParams.pszHostName[0] == '\0') {
  1057.             return;
  1058.         }
  1059.             
  1060.         //  First check to see if it is a dotted IP address
  1061.     
  1062.         NewHostParams.laddr = inet_addr(NewHostParams.pszHostName);
  1063.     
  1064.         if (NewHostParams.laddr == INADDR_NONE) {
  1065.     
  1066.             //  Assume the user gave us an actual host name
  1067.     
  1068.             hAsyncTask = WSAAsyncGetHostByName(hwnd, WM_SOCKET_ASYNC,
  1069.                             NewHostParams.pszHostName, NewHostParams.bBuffer,
  1070.                             sizeof(NewHostParams.bBuffer));
  1071.         } else {
  1072.     
  1073.             //  The user gave us a dotted IP address
  1074.     
  1075.             hAsyncTask = WSAAsyncGetHostByAddr(hwnd, WM_SOCKET_ASYNC,
  1076.                               (CHAR FAR *) &NewHostParams.laddr,
  1077.                               sizeof(NewHostParams.laddr), PF_INET,
  1078.                               NewHostParams.bBuffer, sizeof(NewHostParams.bBuffer));
  1079.         }
  1080.     
  1081.         if (hAsyncTask == NULL) {
  1082.     
  1083.             //  Could not initiate the asynchronous API
  1084.     
  1085.             serr = WSAGetLastError();
  1086.             MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(40),
  1087.                     NewHostParams.pszHostName, serr, SockerrToString(serr));
  1088.             return;
  1089.         }
  1090.     
  1091.         /*  The async command has been issued.  Disable all dialog
  1092.             controls except [Cancel]. */
  1093.     
  1094.         NewHost_EnableControls(hwnd, FALSE);
  1095.     }
  1096. }
  1097.  
  1098. /*    NEWHOST_ONSOCKETASYNC  --  Handles reply from lookup of host
  1099.                                name or IP address.  */
  1100.  
  1101. static VOID NewHost_OnSocketAsync(HWND hwnd, SOCKERR hAsync,
  1102.                                   SOCKERR serr, SOCKEVENT cbBuffer)
  1103. {
  1104.     LPHOSTENT phostent;
  1105.  
  1106.     phostent = (LPHOSTENT) NewHostParams.bBuffer;
  1107.  
  1108.     if (serr != 0) { 
  1109.  
  1110.         //  Error retrieving host name/address
  1111.         
  1112.         if (NewHostParams.laddr == INADDR_NONE) { 
  1113.             MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(41),
  1114.                     NewHostParams.pszHostName, serr, SockerrToString(serr));
  1115.     
  1116.             //  Reenable the dialog controls
  1117.     
  1118.             NewHost_EnableControls(hwnd, TRUE);
  1119.             return;
  1120.         } else {
  1121.             struct in_addr in;
  1122.             
  1123.             in.s_addr = NewHostParams.laddr; 
  1124.             _fstrcpy(NewHostParams.pszHostName, inet_ntoa(in));
  1125.             _fmemcpy(NewHostParams.paddr, &NewHostParams.laddr, sizeof(IN_ADDR));
  1126.             EndDialog(hwnd, TRUE);
  1127.             return;
  1128.         }
  1129.     }
  1130.     
  1131.     //  Found the host
  1132.  
  1133.     _fstrcpy(NewHostParams.pszHostName, phostent->h_name);
  1134.     _fmemcpy(NewHostParams.paddr, phostent->h_addr, sizeof(IN_ADDR));
  1135.  
  1136.     EndDialog(hwnd, TRUE);
  1137. }
  1138.  
  1139. /*    NEWHOST_DLGPROC  --  New host dialogue procedure.  */
  1140.  
  1141. BOOL CALLBACK NewHost_DlgProc(HWND hwnd, UINT nMessage, WPARAM wParam,
  1142.                                LPARAM lParam)
  1143. {
  1144.     switch (nMessage) {
  1145.     
  1146.         case WM_INITDIALOG:
  1147.             Edit_LimitText(GetDlgItem(hwnd, IDD_NEW_HOST), MAX_HOST);
  1148.             EnableWindow(GetDlgItem(hwnd, IDC_NEW_MODEM),
  1149.                 modemHandle != -1 && modemSessions == 0);
  1150.             ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_NAME), SW_SHOW);
  1151.             ShowWindow(GetDlgItem(hwnd, IDD_NEW_HOST_DIAL_STRING), SW_HIDE);
  1152.             break;
  1153.             
  1154.         case WM_COMMAND:
  1155.             NewHost_OnCommand(hwnd, (int) wParam, (HWND) LOWORD(lParam), (UINT) HIWORD(lParam));  
  1156.             break;
  1157.             
  1158.         case WM_SOCKET_ASYNC:
  1159.             NewHost_OnSocketAsync(hwnd, (SOCKET) (wParam),
  1160.                 (SOCKERR) WSAGETSELECTERROR(lParam),
  1161.                 (SOCKEVENT) WSAGETSELECTEVENT(lParam));
  1162.             break;
  1163.     }
  1164.     return FALSE;
  1165. }
  1166.  
  1167. /*    NEWHOSTDIALOGUE  --  Open a new connection to a given host name or
  1168.                          IP number.  */
  1169.  
  1170. BOOL newHostDialogue(HWND hwndParent, LPSTR pszHostName, LPIN_ADDR paddr)
  1171. {
  1172.     FARPROC pfnDlg;
  1173.     BOOL fResult;
  1174.  
  1175.     //  Setup dialog parameters
  1176.  
  1177.     _fmemset(&NewHostParams, 0, sizeof(NewHostParams));
  1178.  
  1179.     NewHostParams.pszHostName = pszHostName;
  1180.     NewHostParams.paddr = paddr;
  1181.     NewHostParams.hAsync = NULL;
  1182.         
  1183.     //  Invoke the dialogue
  1184.     
  1185.     pfnDlg = MakeProcInstance((FARPROC) NewHost_DlgProc, hInst);
  1186.     
  1187.     fResult = DialogBox(hInst, IDD_NEW, hwndParent, (DLGPROC) pfnDlg);
  1188.     
  1189.     //  Cleanup & exit
  1190.     
  1191.     FreeProcInstance(pfnDlg);
  1192.     return fResult;
  1193. }
  1194.  
  1195.  
  1196.  
  1197.  
  1198.